package controllers.admin

import controllers.{LayUiGyErpUser, LayUiKdErpUser, LayUiKddc, RequestAsJson, checkAdmin}
import models.users.SystemUsersStatusName
import play.api.Logging
import play.api.libs.json.{JsValue, Json}
import play.api.mvc.{AbstractController, BodyParsers, Codec, ControllerComponents}
import services.sysusers.SystemUsersService

import javax.inject.{Inject, Singleton}
import scala.concurrent.{ExecutionContext, Future}

/**
 * This controller creates an `Action` to handle HTTP requests to the
 * application's home page.
 */
@Singleton
class SystemUsersController @Inject()(cc: ControllerComponents,
                                      sysUser: SystemUsersService
                                     )(implicit exec: ExecutionContext, parser: BodyParsers.Default)
  extends AbstractController(cc) with play.api.i18n.I18nSupport with RequestAsJson with Logging {
  implicit val myCustomCharset = Codec.javaSupported("gb18030")

  def receive() = Action.async { implicit request =>
    val req = request.body.asJson.getOrElse(Json.obj("sys" -> "", "op" -> "", "data" -> Json.obj()))
    logger.debug(req.toString())
    (req \ "sys").as[String] match {
      case "gyerp" => (req \ "op").as[String] match {
        case "check" => sysUser.gyUserCheck(
          id = (req \ "data" \ "id").as[Long],
          name = (req \ "data" \ "name").as[String],
          mobile = (req \ "data" \ "mobile").as[String].take(20),
          status = 1
        ).map(res =>
          if (res) Ok("Ok")
          else Ok("Del")
        )
        case "off" => sysUser.gyUserSetOff(id = (req \ "data" \ "id").as[Long]).map(res =>
          Ok(res.toString)
        )
        case _ => Future(Ok("gyerp error op"))
      }

      case "k3cloud" => Future(Ok("received k3cloud data"))
      case _ => Future(Ok("received error data"))
    }

  }

  def index(sys: String) = checkAdmin(parser, exec) { implicit request =>
    sys match {
      case "gyerp" => Ok(views.html.sysusers.gyerp(sys, SystemUsersStatusName.idName, sysUser.accountAll))
      case "kderp" => Ok(views.html.sysusers.kderp(sys, SystemUsersStatusName.idName, sysUser.kddcAll, sysUser.accountAll))
      case "kddc" => Ok(views.html.sysusers.kddc(sys))
      case _ => Ok(views.html.sysusers.index(sys, SystemUsersStatusName.idName))
    }

  }

  def osuser(sys: String) = checkAdmin.async { implicit request =>
    logger.debug(request.body.toString())
    val req = request.body.asJson.getOrElse(Json.obj("op" -> ""))
    logger.debug(req.toString())
    sys match {
      case "gyerp" => gyUser(req)
      case "kderp" => kdUser(req)
      case "kddc" => kdDataCenter(req)
      case _ => Future(Ok("sys error"))
    }
  }

  def gyUser(js: JsValue) = {
    try {
      (js \ "op").as[String] match {
        case "create" => Future(Ok("op create"))
        case "update" => Future(Ok("op update"))
        case "onoff" => {
          val id = (js \ "id").as[Long]
          //          val status = (js \ "status").as[Int]
          sysUser.gyUserStatusOnoff(id).map { res =>
            Ok(Json.obj(
              "success" -> (if (res._1 == 1) true else false),
              "status" -> SystemUsersStatusName.statusId(res._2)
            ))
          }
        }
        case "edit" => {
          val id = (js \ "id").as[Long]
          val status = (js \ "status").as[String].toInt
          val user = (js \ "user").as[String].toInt
          sysUser.gyUserUpdate(id, user, status).map {
            res =>
              Ok(s"gyerp edit ${res.toString()}")
          }
        }
        case "list" => {
          val name = (js \ "name").asOpt[String].getOrElse("")
          val mobile = (js \ "mobile").asOpt[String].getOrElse("")
          val status = (js \ "status").asOpt[String].getOrElse("-1").toInt
          val page = (js \ "page").asOpt[Int].getOrElse(1)
          val limit = (js \ "limit").asOpt[Int].getOrElse(10)
          implicit val tableResJson = Json.format[LayUiGyErpUser]
          sysUser.gyUserList(name = name, mobile = mobile, status = status, page = page, limit = limit)
            .map { res =>
              val p = res._1
              //              logger.debug(p.toString())
              val count = res._2
              val data = res._1.map(i =>
                LayUiGyErpUser(
                  id = i._1.id,
                  name = i._1.name,
                  user = i._2.getOrElse(""),
                  account = i._1.mobile,
                  status = SystemUsersStatusName.statusId(i._1.status),
                  disable = i._1.disable_time.map(f => f.toString.split('.')(0)).getOrElse("")
                ))
              Ok(Json.obj("code" -> 0, "message" -> "", "count" -> count, "data" -> Json.toJson(data)))
            }
        }
        case "del" => sysUser.gyUserDel((js \ "id").as[Long]).map {
          res =>
            val str = if (res == 1) "成功" else "失败"
            Ok(s"gyerp del $str")
        }
        case _ => Future(Ok("op error"))
      }

    } catch {
      case exception: Exception =>
        logger.error(s"gyUser Operation: ${js.toString}", exception);
        Future(Ok("json error"))
    }
  }

  def kdUser(js: JsValue) = {
    try {
      (js \ "op").as[String] match {
        case "create" => Future(Ok("op create"))
        case "update" => Future(Ok("op update"))
        case "onoff" => {
          val id = (js \ "id").as[Long]
          //          val status = (js \ "status").as[Int]
          sysUser.kdUserDel(id).map {
            res =>
              Ok(Json.obj(
                "success" -> (if (res._1 == 1) true else false),
                "status" -> SystemUsersStatusName.statusId(res._2)
              ))
          }
        }
        case "edit" => {
          val id = (js \ "id").as[Long]
          val status = (js \ "status").as[String].toInt
          val user = (js \ "user").as[String].toInt
          sysUser.kdUserUpdate(id, user, status)
          Future(Ok(s"kderp edit ${js.toString()}"))
        }
        case "list" => {
          val name = (js \ "name").asOpt[String].getOrElse("")
          val mobile = (js \ "mobile").asOpt[String].getOrElse("")
          val status = (js \ "status").asOpt[String].getOrElse("-1").toInt
          val page = (js \ "page").asOpt[Int].getOrElse(1)
          val limit = (js \ "limit").asOpt[Int].getOrElse(10)
          implicit val tableResJson = Json.format[LayUiKdErpUser]
          sysUser.kdUserList(name = name, mobile = mobile, status = status, page = page, limit = limit)
            .map { res =>
              val p = res._1
              logger.debug(p.toString())
              val count = res._2
              val data = res._1.map(i =>
                LayUiKdErpUser(
                  id = i._1.id,
                  kddc = i._3.getOrElse(""),
                  name = i._1.name,
                  user = i._2.getOrElse(""),
                  mobile = i._1.mobile,
                  status = SystemUsersStatusName.statusId(i._1.status),
                  disable = i._1.disable_time.map(f => f.toString.split('.')(0)).getOrElse(""),
                  forbid_status = i._1.forbid_status,
                  fAppGroup = i._1.fAppGroup
                ))
              Ok(Json.obj("code" -> 0, "message" -> "", "count" -> count, "data" -> Json.toJson(data)))
            }
        }
        case _ => Future(Ok("op error"))
      }

    } catch {
      case exception: Exception =>
        logger.error(s"kdUser Operation: ${js.toString}", exception);
        Future(Ok("json error"))
    }
  }

  def kdDataCenter(js: JsValue) = {
    try {
      (js \ "op").as[String] match {
        case "add" => sysUser.kddcAdd(js("data").as[JsValue]).map(r => Ok(js))

        case "edit" => sysUser.kddcEdit(js("data").as[JsValue]).map(r => Ok(js))
        case "list" => {
          val page = (js \ "page").asOpt[Int].getOrElse(1)
          val limit = (js \ "limit").asOpt[Int].getOrElse(10)
          implicit val tableResJson = Json.format[LayUiKddc]
          sysUser.kddcList(page = page, limit = limit)
            .map { res =>
              val p = res._1
              logger.debug(p.toString())
              val count = res._2
              val data = res._1.map(i =>
                LayUiKddc(
                  id = i.id,
                  name = i.name,
                  test = if (i.test) "测试" else "正式"
                ))
              Ok(Json.obj("code" -> 0, "message" -> "", "count" -> count, "data" -> Json.toJson(data)))
            }
        }
        case _ => Future(Ok("op error"))
      }

    } catch {
      case exception: Exception =>
        logger.error(s"kdUser Operation: ${js.toString}", exception);
        Future(Ok("json error"))
    }
  }
}



